第21章 错误处理与调试

JS 通过 try/catch 语句进行错误捕获

try {
  // 可能出错的代码
} catch (error) { 
  // 出错时要做什么
} finally {
  // 无论是否有错误,都会运行
}

JS 定义了以下 8 种错误类型:

为了处理不同的错误,可以在 try/catch 语句的 catch 块中使用 instanceof 操作符确定错误类型:

try {
  someFunction();
} catch (error) {
  if (error instanceof TypeError) {
        // 处理类型错误    
  } else if (error instanceof ReferenceError) {
    // 处理引用错误
  } else {
    // 处理所有其他类型的错误
  }
}

与 try/catch 语句对应的一个机制是 throw 操作符,用于在任何时候抛出自定义错误。throw 操作符必须有一个值,但值的类型不限:

throw 12345;
throw "Hello world!";
throw true;
throw { name: "JavaScript" };
// 可以调用指定错误类型的构造函数创建相对应的错误
throw new Error("Something bad happened.");
throw new SyntaxError("I don't like your syntax.");

通过继承 Error 也可以创建自定义的错误类型。创建自定义错误类型时,需要提供 name 属性和 message 属性:

class CustomError extends Error {
  constructor(message) {
    super(message);
    this.name = "CustomError";
    this.message = message;
  } 
}
throw new CustomError("My message");

任何没有被 try/catch 语句处理的错误都会在 window 对象上触发 error 事件。在 onerror 事件处理程序中,浏览器会传入 3 个参数:错误消息、发生错误的 URL 和行号。

window.onerror = (message, url, line) => {
  console.log(message);
  // 可以返回 false 来阻止浏览器默认报告错误的行为
  return false;
};

自定义错误通常使用 assert() 函数抛出,该函数接收一个应该为 true 的条件,并在条件为 false 时抛出错误

function divide(num1, num2) {
  assert(typeof num1 == "number" && typeof num2 == "number",
         "divide(): Both arguments must be numbers.");
  return num1 / num2;
}